home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail.cf / src / headerkludge.c next >
Encoding:
C/C++ Source or Header  |  1987-02-23  |  5.2 KB  |  258 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. char *alloc(), *stralloc();
  5.  
  6. #define ALLOC(type)        ((type *)alloc(sizeof(type)))
  7.  
  8. struct headerline {
  9.     char *hl_line;
  10.     struct headerline *hl_next;
  11. };
  12.  
  13. struct header {
  14.     struct headerline *h_header;
  15.     struct header *h_next;
  16. } *headerlist, *get_header();
  17.  
  18. struct headerfifo {
  19.     struct header *f_head;
  20.     struct header *f_tail;
  21. } saveheaderlist;
  22.  
  23. main(argc, argv)
  24.     int argc;
  25.     char **argv;
  26. {
  27.     int i;
  28.     char *inputfile = NULL, *outputfile = NULL;
  29.     
  30.     for (argc--, argv++; argc && **argv == '-'; argc -= i, argv += i) {
  31.     i = 1;
  32.     while (*++*argv) {
  33.         switch (**argv) {
  34.         case 'h':
  35.             if (argc <= i) {
  36.             fprintf(stderr, "-%c: not enough args\n", **argv);
  37.             exit(-1);
  38.             }
  39.             getheaders(&headerlist, argv[i++]);
  40.             break;
  41.         case 'o':
  42.             if (argc <= i) {
  43.             fprintf(stderr, "-%c: not enough args\n", **argv);
  44.             exit(-1);
  45.             }
  46.             outputfile = argv[i++];
  47.             break;
  48.         default:
  49.             fprintf(stderr,"Unknown switch '-%c'\n",**argv);
  50.             exit(-1);
  51.         }
  52.     }
  53.     }
  54.  
  55.     if (argc > 1) {
  56.     fprintf(stderr,
  57. "usage: headerkludge [-a headerlist] [-h headerlist] [-o output] [input]\n");
  58.     exit(-1);
  59.     } else if (argc == 1)
  60.     inputfile = *argv;
  61.  
  62.     parse_input(inputfile, outputfile);
  63. }
  64.  
  65. parse_input(input, output)
  66.     char *input, *output;
  67. {
  68.     FILE *infp, *outfp;
  69.     char buffer[BUFSIZ], *lp, *fgets();
  70.     struct header *hp;
  71.  
  72.     if (input && (strcmp(input, "-") != 0)) {
  73.     if ((infp = fopen(input, "r")) == NULL) {
  74.         perror(input);
  75.         exit(-1);
  76.     }
  77.     } else
  78.     infp = stdin;
  79.  
  80.     if (output && (strcmp(output, "-") != 0)) {
  81.     if ((outfp = fopen(output, "r")) == NULL) {
  82.         perror(output);
  83.         exit(-1);
  84.     }
  85.     } else
  86.     outfp = stdout;
  87.  
  88.     lp = fgets(buffer, BUFSIZ, infp);
  89.  
  90.     for ( ; lp != NULL && !end_of_headers(lp); ) {
  91.     hp = get_header(&lp, BUFSIZ, infp);
  92.     if (want_header(headerlist, hp))
  93.         print_header(outfp, hp);
  94.     else
  95.         save_header(&saveheaderlist, hp);
  96.     }
  97.  
  98.     /* If there is more input, or saved headers to output,
  99.      *  indicate end_of_headers by outputting blank line
  100.      */
  101.     if (!feof(infp) || saveheaderlist.f_head)
  102.     fprintf(outfp, "\n");
  103.  
  104.     /* Output saved headers */
  105.     for (hp = saveheaderlist.f_head; hp != (struct header *)NULL;
  106.         hp = hp->h_next)
  107.     print_header(outfp, hp);
  108.  
  109.     /* Finish output */
  110.     if (!feof(infp)) {
  111.     /* Output a separator (blank line) */
  112.     fprintf(outfp, "\n");
  113.     while (fgets(buffer, BUFSIZ, infp))
  114.         fprintf(outfp, "%s", buffer);
  115.     }
  116.  
  117.     fclose(infp);
  118.     fclose(outfp);
  119. }
  120.  
  121. /* Return true if the string represents the end-of-header field
  122.  * (for now, this is a blank line)
  123.  */
  124. end_of_headers(str)
  125.     char *str;
  126. {
  127.     while (str && *str && isspace(*str)) str++;
  128.     return (!str || !*str);
  129. }
  130.  
  131. want_header(hl, hptr)
  132.     struct header *hl, *hptr;
  133. {
  134.     char buffer[BUFSIZ], *bp, *str;
  135.     struct header *hp;
  136.  
  137.     str = hptr->h_header->hl_line;
  138.  
  139.     for (bp = buffer; *str && !ispunct(*str) && !isspace(*str);)
  140.     if (isupper(*str))
  141.         *bp++ = tolower(*str++);
  142.     else
  143.         *bp++ = *str++;
  144.     *bp = '\0';
  145.  
  146.     for (hp = hl; hp; hp = hp->h_next)
  147.     if (strcmp(buffer, hp->h_header->hl_line) == 0)
  148.         return (1);
  149.  
  150.     return (0);
  151. }
  152.  
  153.     struct header *
  154. get_header(str, len, fp)
  155.     char **str;
  156.     int len;
  157.     FILE *fp;
  158. {
  159.     struct header *hp;
  160.     struct headerline **hl;
  161.  
  162.     hp = ALLOC(struct header);
  163.     hp->h_next = (struct header *)NULL;
  164.     hl = &(hp->h_header);
  165.  
  166.     /* Read and save all header lines
  167.      *  header continuation lines begin with whitespace (but are not
  168.      *  the blank line at the end of the headers).
  169.      *  The first header line has already been read.
  170.      */
  171.     do {
  172.     *hl = ALLOC(struct headerline);
  173.     (*hl)->hl_line = stralloc(*str);
  174.     (*hl)->hl_next = (struct headerline *)NULL;
  175.     hl = &((*hl)->hl_next);
  176.     *str = fgets(*str, len, fp);
  177.     } while (*str && isspace(**str) && !end_of_headers(*str));
  178.  
  179.     return (hp);
  180. }
  181.  
  182. save_header(fifo, hp)
  183.     struct headerfifo *fifo;
  184.     struct header *hp;
  185. {
  186.     fifoappend(fifo, hp);
  187. }
  188.  
  189. print_header(fp, hp)
  190.     struct header *hp;
  191.     FILE *fp;
  192. {
  193.     struct headerline *hl;
  194.  
  195.     for (hl = hp->h_header; hl != (struct headerline *)NULL; hl = hl->hl_next)
  196.     fprintf(fp, "%s", hl->hl_line);
  197. }
  198.  
  199. getheaders(hl, str)
  200.     struct header **hl;
  201.     char *str;
  202. {
  203.     char buffer[BUFSIZ], *bp;
  204.     struct header *hp;
  205.  
  206.     while (str && *str) {
  207.     for (bp = buffer; *str && !ispunct(*str) && !isspace(*str);)
  208.         if (isupper(*str))
  209.         *bp++ = tolower(*str++);
  210.         else
  211.         *bp++ = *str++;
  212.     *bp = '\0';
  213.     hp = ALLOC(struct header);
  214.     hp->h_header = ALLOC(struct headerline);
  215.     hp->h_header->hl_next = (struct headerline *)NULL;
  216.     hp->h_header->hl_line = stralloc(buffer);
  217.     hp->h_next = *hl;
  218.     *hl = hp;
  219.     /* Skip to the next header */
  220.     while (*str && (ispunct(*str) || isspace(*str))) str++;
  221.     }
  222. }
  223.  
  224.     char *
  225. stralloc(str)
  226.     char *str;
  227. {
  228.     char *sp;
  229.  
  230.     sp = alloc((unsigned)strlen(str)+1);
  231.     strcpy(sp, str);
  232.     return (sp);
  233. }
  234.  
  235.     char *
  236. alloc(n)
  237.     unsigned n;
  238. {
  239.     char *dp, *malloc();
  240.  
  241.     if ((dp = malloc(n)) == NULL) {
  242.     fprintf(stderr, "can't malloc %d bytes\n", n);
  243.     exit(-1);
  244.     }
  245.     return (dp);
  246. }
  247.  
  248. fifoappend(fifo, hp)
  249.     struct headerfifo *fifo;
  250.     struct header *hp;
  251. {
  252.     if (fifo->f_tail)
  253.     fifo->f_tail->h_next = hp;
  254.     else
  255.     fifo->f_head = hp;
  256.     fifo->f_tail = hp;
  257. }
  258.